package hit.reports;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Iterator;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Font.FontStyle;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * A builder used to create an PDF copy of the report.
 *
 */
public class PDFBuilder extends ReportBuilder {

	private Font titleFont;
	private Font headerFont;
	private Font colHeadFont;
	
	public PDFBuilder()
	{
		titleFont = new Font();
		titleFont.setSize(16);
		titleFont.setStyle(Font.BOLD);
		
		headerFont = new Font();
		headerFont.setSize(14);
		headerFont.setStyle(Font.BOLD);
		
		colHeadFont = new Font();
		colHeadFont.setSize(11);
		colHeadFont.setStyle(Font.BOLD);
	}
	
	/**
	 * Prints the report to PDF, and saves it to the file provided
	 * @param toSave Where to save the new report.
	 * @return The location where the file was saved.
	 * @throws UnsupportedOperationException if the builder contains
	 * 	a {@link BuilderObject} not yet implemented.
	 * @throws IllegalArgumentException if toSave is null.
	 */
	public File GetOutput(File toSave) throws IllegalArgumentException,
												UnsupportedOperationException
	{
		if (toSave == null)
			throw new IllegalArgumentException();
		
		try
		{
			Document document = new Document(PageSize.LETTER.rotate());
			
			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(toSave));
			writer.setInitialLeading(16);
			document.open();
			
			Paragraph title = new Paragraph();
			title.setAlignment(Paragraph.ALIGN_CENTER);
			title.setFont(titleFont);
			title.add(new Chunk(getTitle()));
			
			document.add(title);
			
			document.add(Chunk.NEWLINE);
			
			Iterator<BuilderObject> iter = this.GetObjectsIterator();
			
			while (iter.hasNext())
			{
				BuilderObject temp = iter.next();
				
				if (temp instanceof BuilderHeader)
				{
					Paragraph newHeader = new Paragraph();
					newHeader.setFont(headerFont);
					newHeader.add(new Chunk(((BuilderHeader)temp).getValue()));
					document.add(newHeader);
					document.add(Chunk.NEWLINE);
				}
				else if (temp instanceof BuilderParagraph)
				{
					Chunk newParagraph = new Chunk(((BuilderParagraph)temp).getValue());
					document.add(newParagraph);
					document.add(Chunk.NEWLINE);
				}
				else if (temp instanceof BuilderTable)
				{
					BuilderTable table = (BuilderTable)temp;
					PdfPTable pdfTable = new PdfPTable(table.GetColumnCount());
					pdfTable.setWidthPercentage(100);
					
					Iterator<TableColumn> colIter = table.GetColumnIterator();
					
					while (colIter.hasNext())
					{
						TableColumn col = colIter.next();
						Phrase cellValue = new Phrase();
						cellValue.setFont(colHeadFont);
						cellValue.add(new Chunk(col.getTitle()));
						PdfPCell cell = new PdfPCell(cellValue);
						pdfTable.addCell(cell);
					}
					
					Iterator<TableRow> rowIter = table.GetRowIterator();
					
					while (rowIter.hasNext())
					{
						TableRow row = rowIter.next();
						colIter = table.GetColumnIterator();
						
						while (colIter.hasNext())
						{
							TableColumn col = colIter.next();
							
							String cellValue = row.GetItemValue(col);
							
							if (cellValue == null)
								cellValue = "";
							
							PdfPCell cell = new PdfPCell(new Phrase(cellValue));
							pdfTable.addCell(cell);
						}
					}
					
					document.add(pdfTable);
				}
				else if (temp instanceof BuilderBreak)
				{
					document.add(Chunk.NEWLINE);
				}
				else
				{
					throw new UnsupportedOperationException();
				}
				
			}

			document.close();
		}
		catch(Exception ex)
		{
		}
		
		return toSave;
	}
}
